<html>
	<head>
		<script type="text/javascript" src="../js/coverreport.js">

		</script><script type="text/javascript">
			RANGES_4 = [
   [11,9,11,91,'dccv']
, [13,9,13,43,'dccv']
, [14,9,14,10,'dccv']
, [15,13,15,25,'dccv']
, [16,9,16,10,'dccv']
, [19,9,19,10,'dccv']
, [20,13,20,69,'dccv']
, [22,13,22,20,'dccv']
, [22,45,22,60,'dccv']
, [22,23,22,41,'dccv']
, [23,13,23,14,'dccv']
, [24,17,24,59,'dccv']
, [25,13,25,14,'dccv']
, [22,42,22,44,'dccv']
, [27,13,27,20,'dccv']
, [27,42,27,58,'dccv']
, [27,23,27,38,'dccv']
, [28,13,28,14,'dccv']
, [29,17,29,58,'dccv']
, [30,13,30,14,'dccv']
, [27,39,27,41,'dccv']
, [31,9,31,10,'dccv']
, [34,9,34,10,'dccv']
, [35,13,35,20,'dccv']
, [35,42,35,53,'dccv']
, [35,23,35,38,'dccv']
, [36,13,36,14,'dccv']
, [37,17,37,61,'dccv']
, [41,13,41,14,'dccv']
, [35,39,35,41,'dccv']
, [42,9,42,10,'dccv']
, [45,9,45,10,'dccv']
, [46,13,46,20,'dccv']
, [46,42,46,53,'dccv']
, [46,23,46,38,'dccv']
, [47,13,47,14,'dccv']
, [48,17,48,55,'dccv']
, [52,13,52,14,'dccv']
, [46,39,46,41,'dccv']
, [53,9,53,10,'dccv']
, [56,9,56,10,'dccv']
, [57,13,57,48,'dccv']
, [58,13,58,20,'dccv']
, [58,42,58,82,'dccv']
, [58,23,58,38,'dccv']
, [59,13,59,14,'dccv']
, [60,17,60,75,'dccv']
, [61,17,61,18,'dccv']
, [62,21,62,39,'dccv']
, [63,17,63,18,'dccv']
, [64,13,64,14,'dccv']
, [58,39,58,41,'dccv']
, [65,13,65,27,'dccv']
, [66,9,66,10,'dccv']
, [69,9,69,10,'dccv']
, [70,13,70,55,'dccv']
, [71,13,71,20,'dccv']
, [71,44,71,85,'dccv']
, [71,23,71,40,'dccv']
, [72,13,72,14,'dccv']
, [73,17,73,46,'dccv']
, [74,17,74,18,'dccv']
, [75,21,75,47,'dccv']
, [76,17,76,18,'dccv']
, [77,13,77,14,'dccv']
, [71,41,71,43,'dccv']
, [78,13,78,34,'dccv']
, [79,9,79,10,'dccv']
, [82,9,82,10,'dccv']
, [83,13,83,63,'dccv']
, [84,13,88,86,'dccv']
, [89,9,89,10,'dccv']
, [93,9,93,10,'dccv']
, [94,13,94,75,'dccv']
, [95,13,95,37,'dccv']
, [100,13,100,89,'dccv']
, [101,13,101,37,'dccv']
, [102,13,102,14,'dccv']
, [103,17,103,30,'dccv']
, [112,9,112,10,'dccv']
, [115,9,115,10,'dccv']
, [116,13,116,84,'dccv']
, [117,13,117,47,'dccv']
, [122,13,122,111,'dccv']
, [123,13,123,43,'dccv']
, [124,13,124,14,'dccv']
, [125,16,125,29,'dccv']
, [134,9,134,10,'dccv']
, [149,9,149,10,'dccv']
, [150,13,150,84,'dccv']
, [151,13,151,14,'dccv']
, [152,17,152,75,'dccv']
, [155,9,155,10,'dccv']
, [158,9,158,10,'dccv']
, [159,13,159,53,'dccv']
, [160,13,160,42,'dccv']
, [161,13,161,20,'dccv']
, [161,42,161,62,'dccv']
, [161,39,161,41,'dccv']
, [165,13,165,32,'dccv']
, [166,9,166,10,'dccv']
, [38,17,38,18,'dcuc']
, [39,21,39,28,'dcuc']
, [49,17,49,18,'dcuc']
, [50,21,50,28,'dcuc']
, [96,13,96,14,'dcuc']
, [97,17,97,30,'dcuc']
, [106,13,110,61,'dcuc']
, [111,13,111,25,'dcuc']
, [118,13,118,14,'dcuc']
, [119,17,119,30,'dcuc']
, [128,13,128,113,'dcuc']
, [129,13,129,129,'dcuc']
, [130,13,130,103,'dcuc']
, [131,13,131,49,'dcuc']
, [133,13,133,25,'dcuc']
, [154,13,154,25,'dcuc']
, [161,23,161,38,'dcuc']
, [162,13,162,14,'dcuc']
, [163,17,163,74,'dcuc']
, [164,13,164,14,'dcuc']
];
		</script><link rel="stylesheet" type="text/css" href="../css/coverreport.css" />
	</head><body>
		<code id="src4" class="dotCoverSource"><pre>using System;
using System.Collections;
using System.Reflection;
using System.Windows.Forms;

namespace BookFinder
{
    public class ViewModelBase
    {
        protected Control View;
        private BindingFlags myBindingFlags = BindingFlags.Instance | BindingFlags.Public;

        public ViewModelBase(Control view)
        {
            View = view;
        }

        protected void BindToView()
        {
            ArrayList allControls = AllControlsDescendingFrom(View);

            foreach ( MethodInfo handler in EventHandlers() )
            {
                FindEventToListenTo(allControls, handler);
            }

            foreach ( FieldInfo field in PropertyFields() )
            {
                FindPropertyToBindTo(allControls, field);
            }
        }

        private void FindPropertyToBindTo(ArrayList allControls, FieldInfo field)
        {
            foreach ( Control control in allControls )
            {
                if ( BindPropertyToControl(control, field) )
                {
                    return;
                }
            }
        }

        private void FindEventToListenTo(ArrayList allControls, MethodInfo handler)
        {
            foreach ( Control control in allControls )
            {
                if ( ListenToEvent(control, handler) )
                {
                    return;
                }
            }
        }

        public IEnumerable PropertyFields()
        {
            ArrayList fields = new ArrayList();
            foreach ( FieldInfo field in this.GetType().GetFields(myBindingFlags) )
            {
                if ( typeof (Property).IsAssignableFrom(field.FieldType) )
                {
                    fields.Add(field);
                }
            }
            return fields;
        }

        private IEnumerable EventHandlers()
        {
            ArrayList eventHandlers = new ArrayList();
            foreach ( MethodInfo method in this.GetType().GetMethods(myBindingFlags) )
            {
                if ( isEventHandler(method) )
                {
                    eventHandlers.Add(method);
                }
            }
            return eventHandlers;
        }

        private bool isEventHandler(MethodInfo info)
        {
            ParameterInfo[] parameters = info.GetParameters();
            return
                (info.ReturnType == typeof (void) &amp;&amp;
                 parameters.Length == 2 &amp;&amp;
                 parameters[0].ParameterType == typeof (object) &amp;&amp;
                 (typeof (EventArgs)).IsAssignableFrom(parameters[1].ParameterType));
        }


        private bool ListenToEvent(Control control, MethodInfo method)
        {
            string eventName = ControlAttributeName(control, method.Name);
            if ( eventName == null )
            {
                return false;
            }

            EventInfo eventInfo = control.GetType().GetEvent(eventName, myBindingFlags);
            if ( eventInfo == null )
            {
                return false;
            }

            eventInfo.GetAddMethod().Invoke(control, new object[]
                                                         {
                                                             Delegate.CreateDelegate(eventInfo.EventHandlerType, this,
                                                                                     method.Name)
                                                         });
            return true;
        }

        private bool BindPropertyToControl(Control control, FieldInfo field)
        {
            string controlPropertyName = ControlAttributeName(control, field.Name);
            if ( controlPropertyName == null )
            {
                return false;
            }

            PropertyInfo controlProperty = control.GetType().GetProperty(controlPropertyName, myBindingFlags);
            if ( controlProperty == null )
            {
               return false;
            }

            BoundPropertyStrategy propertyStorageStrategy = new BoundPropertyStrategy(control, controlProperty);
            ConstructorInfo propertyConstructor = field.FieldType.GetConstructor(new Type[] {typeof (PropertyStorageStrategy)});
            object propertyField = propertyConstructor.Invoke(new object[] {propertyStorageStrategy});
            field.SetValue(this, propertyField);

            return true;
        }

        /// &lt;summary&gt;
        /// Given a control and a ViewModel member, checks to see if the control name
        /// prefixes the viewModelMember. If so, returns the remainder of the member name.
        /// Otherwise, returns &lt;c&gt;null&lt;/c&gt;. 
        /// &lt;/summary&gt;
        /// &lt;remarks&gt;
        /// Used to find controls that contain attributes that we can bind to. For example,
        /// given a control called &quot;Search&quot;, and a viewModelMember called &quot;SearchClick&quot;, this 
        /// method should return &quot;Click&quot;, allowing us to look for the &lt;c&gt;control.Click&lt;/c&gt; member.
        /// Given a control called &quot;Save&quot; and a viewModelMember called &quot;SearchClick&quot;, the 
        /// method will return &lt;c&gt;null&lt;/c&gt; - there's nothing here to try to bind to.
        /// &lt;/remarks&gt;
        private string ControlAttributeName(Control control, string viewModelMemberName)
        {
            if ( viewModelMemberName.ToLower().StartsWith(control.Name.ToLower()) )
            {
                return viewModelMemberName.Substring(control.Name.Length);
            }
            return null;
        }

        private static ArrayList AllControlsDescendingFrom(Control baseControl)
        {
            ArrayList allControls = new ArrayList();
            allControls.Add(baseControl);
            foreach ( Control control in baseControl.Controls )
            {
                allControls.AddRange(AllControlsDescendingFrom(control));
            }
            return allControls;
        }
       }
}
</pre></code><script type="text/javascript">
			applyranges('src4', RANGES_4)
		</script>
	</body>
</html>